"""
定时任务API路由
提供类似xxl-job-admin的Web API接口
"""
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from typing import Optional, List
from datetime import date
from uuid import UUID

from app.database.base import get_db
from app.core.auth import get_current_user
from app.models.user import User
from app.services.scheduled_job import ScheduledJobService
from app.schemas.scheduled_job import (
    JobCreate, JobUpdate, JobResponse, JobListResponse,
    JobLogResponse, JobLogListResponse, JobTrigger, JobStatusUpdate,
    JobGroupCreate, JobGroupUpdate, JobGroupResponse,
    JobStatistics, JobExecutionTrend, JobStatus
)
from app.core.scheduler import job_scheduler

router = APIRouter(prefix="/scheduled-jobs", tags=["定时任务管理"])
job_service = ScheduledJobService()


# ==================== 任务管理接口 ====================

@router.post("/", response_model=JobResponse, status_code=status.HTTP_201_CREATED)
async def create_job(
    job_data: JobCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """创建定时任务"""
    # 检查任务名称是否已存在
    existing_job = job_service.get_job_by_name(db, job_data.job_name)
    if existing_job:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="任务名称已存在"
        )
    
    # 创建任务
    job = job_service.create_job(db, job_data, str(current_user.id))
    
    # 如果任务是激活状态，添加到调度器
    if str(job.job_status) == JobStatus.ACTIVE.value:
        job_scheduler.add_job_from_db(job)
    
    return JobResponse.from_orm(job)


@router.get("/", response_model=JobListResponse)
async def get_jobs(
    skip: int = Query(0, ge=0, description="跳过记录数"),
    limit: int = Query(100, ge=1, le=1000, description="返回记录数"),
    job_group: Optional[str] = Query(None, description="任务分组"),
    job_status: Optional[str] = Query(None, description="任务状态"),
    job_type: Optional[str] = Query(None, description="任务类型"),
    search: Optional[str] = Query(None, description="搜索关键词"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取任务列表"""
    jobs, total = job_service.get_jobs(
        db, skip=skip, limit=limit,
        job_group=job_group, job_status=job_status,
        job_type=job_type, search=search
    )
    
    return JobListResponse(
        items=[JobResponse.from_orm(job) for job in jobs],
        total=total,
        page=skip // limit + 1,
        per_page=limit,
        pages=(total + limit - 1) // limit
    )


@router.get("/{job_id}", response_model=JobResponse)
async def get_job(
    job_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取任务详情"""
    job = job_service.get_job(db, job_id)
    if not job:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务不存在"
        )
    return JobResponse.from_orm(job)


@router.put("/{job_id}", response_model=JobResponse)
async def update_job(
    job_id: UUID,
    job_data: JobUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """更新任务"""
    job = job_service.update_job(db, job_id, job_data, str(current_user.id))
    if not job:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务不存在"
        )
    
    # 重新加载调度器中的任务
    job_scheduler.reload_job_from_db(job_id)
    
    return JobResponse.from_orm(job)


@router.delete("/{job_id}")
async def delete_job(
    job_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """删除任务"""
    # 先从调度器移除
    job_scheduler.remove_job(job_id)
    
    # 从数据库删除
    success = job_service.delete_job(db, job_id)
    if not success:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务不存在"
        )
    
    return {"message": "任务删除成功"}


# ==================== 任务操作接口 ====================

@router.post("/{job_id}/start")
async def start_job(
    job_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """启动任务"""
    from app.models.scheduled_job import JobStatus as ModelJobStatus
    job = job_service.update_job_status(db, job_id, ModelJobStatus.ACTIVE)
    if not job:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务不存在"
        )
    
    # 添加到调度器
    job_scheduler.add_job_from_db(job)
    
    return {"message": "任务启动成功"}


@router.post("/{job_id}/stop")
async def stop_job(
    job_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """停止任务"""
    from app.models.scheduled_job import JobStatus as ModelJobStatus
    job = job_service.update_job_status(db, job_id, ModelJobStatus.INACTIVE)
    if not job:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务不存在"
        )
    
    # 从调度器移除
    job_scheduler.remove_job(job_id)
    
    return {"message": "任务停止成功"}


@router.post("/{job_id}/pause")
async def pause_job(
    job_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """暂停任务"""
    from app.models.scheduled_job import JobStatus as ModelJobStatus
    job = job_service.update_job_status(db, job_id, ModelJobStatus.PAUSED)
    if not job:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务不存在"
        )
    
    # 暂停调度器中的任务
    job_scheduler.pause_job(job_id)
    
    return {"message": "任务暂停成功"}


@router.post("/{job_id}/resume")
async def resume_job(
    job_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """恢复任务"""
    from app.models.scheduled_job import JobStatus as ModelJobStatus
    job = job_service.update_job_status(db, job_id, ModelJobStatus.ACTIVE)
    if not job:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务不存在"
        )
    
    # 恢复调度器中的任务
    job_scheduler.resume_job(job_id)
    
    return {"message": "任务恢复成功"}


@router.post("/{job_id}/trigger")
async def trigger_job(
    job_id: UUID,
    trigger_data: JobTrigger,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """手动触发任务"""
    # 检查任务是否存在
    job = job_service.get_job(db, job_id)
    if not job:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务不存在"
        )
    
    # 手动触发任务
    success = job_scheduler.trigger_job(job_id, trigger_data.executor_params)
    if not success:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="任务触发失败"
        )
    
    return {"message": "任务触发成功"}


@router.patch("/{job_id}/status", response_model=JobResponse)
async def update_job_status(
    job_id: UUID,
    status_data: JobStatusUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """更新任务状态"""
    from app.models.scheduled_job import JobStatus as ModelJobStatus
    
    # 将Schema的JobStatus转换为Model的JobStatus
    model_status = ModelJobStatus(status_data.job_status.value)
    job = job_service.update_job_status(db, job_id, model_status)
    if not job:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务不存在"
        )
    
    # 根据状态更新调度器
    if status_data.job_status == JobStatus.ACTIVE:
        job_scheduler.add_job_from_db(job)
    elif status_data.job_status == JobStatus.INACTIVE:
        job_scheduler.remove_job(job_id)
    elif status_data.job_status == JobStatus.PAUSED:
        job_scheduler.pause_job(job_id)
    
    return JobResponse.from_orm(job)


# ==================== 任务日志接口 ====================

@router.get("/{job_id}/logs", response_model=JobLogListResponse)
async def get_job_logs(
    job_id: UUID,
    skip: int = Query(0, ge=0, description="跳过记录数"),
    limit: int = Query(100, ge=1, le=1000, description="返回记录数"),
    status: Optional[str] = Query(None, description="执行状态"),
    start_date: Optional[date] = Query(None, description="开始日期"),
    end_date: Optional[date] = Query(None, description="结束日期"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取任务执行日志"""
    logs, total = job_service.get_job_logs(
        db, job_id=job_id, skip=skip, limit=limit,
        status=status, start_date=start_date, end_date=end_date
    )
    
    return JobLogListResponse(
        items=logs,
        total=total,
        page=skip // limit + 1,
        per_page=limit,
        pages=(total + limit - 1) // limit
    )


@router.get("/logs", response_model=JobLogListResponse)
async def get_all_job_logs(
    skip: int = Query(0, ge=0, description="跳过记录数"),
    limit: int = Query(100, ge=1, le=1000, description="返回记录数"),
    status: Optional[str] = Query(None, description="执行状态"),
    start_date: Optional[date] = Query(None, description="开始日期"),
    end_date: Optional[date] = Query(None, description="结束日期"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取所有任务执行日志"""
    logs, total = job_service.get_job_logs(
        db, skip=skip, limit=limit,
        status=status, start_date=start_date, end_date=end_date
    )
    
    return JobLogListResponse(
        items=logs,
        total=total,
        page=skip // limit + 1,
        per_page=limit,
        pages=(total + limit - 1) // limit
    )


# ==================== 任务分组接口 ====================

@router.post("/groups/", response_model=JobGroupResponse, status_code=status.HTTP_201_CREATED)
async def create_job_group(
    group_data: JobGroupCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """创建任务分组"""
    # 检查分组名称是否已存在
    existing_group = job_service.get_job_group_by_name(db, group_data.group_name)
    if existing_group:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="分组名称已存在"
        )
    
    group = job_service.create_job_group(db, group_data)
    return group


@router.get("/groups/")
async def get_job_groups(
    skip: int = Query(0, ge=0, description="跳过记录数"),
    limit: int = Query(100, ge=1, le=1000, description="返回记录数"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取任务分组列表"""
    groups, total = job_service.get_job_groups(db, skip=skip, limit=limit)
    
    return {
        "items": groups,
        "total": total,
        "page": skip // limit + 1,
        "per_page": limit,
        "pages": (total + limit - 1) // limit
    }


@router.get("/groups/{group_id}", response_model=JobGroupResponse)
async def get_job_group(
    group_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取任务分组详情"""
    group = job_service.get_job_group(db, group_id)
    if not group:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务分组不存在"
        )
    return group


@router.put("/groups/{group_id}", response_model=JobGroupResponse)
async def update_job_group(
    group_id: UUID,
    group_data: JobGroupUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """更新任务分组"""
    group = job_service.update_job_group(db, group_id, group_data)
    if not group:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="任务分组不存在"
        )
    return group


@router.delete("/groups/{group_id}")
async def delete_job_group(
    group_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """删除任务分组"""
    success = job_service.delete_job_group(db, group_id)
    if not success:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="任务分组不存在或有任务正在使用该分组"
        )
    
    return {"message": "任务分组删除成功"}


# ==================== 统计和监控接口 ====================

@router.get("/statistics/overview", response_model=JobStatistics)
async def get_job_statistics(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取任务统计概览"""
    stats = job_service.get_job_statistics(db)
    return JobStatistics(**stats)


@router.get("/statistics/trend")
async def get_execution_trend(
    days: int = Query(7, ge=1, le=30, description="统计天数"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取任务执行趋势"""
    trend_data = job_service.get_execution_trend(db, days)
    return [JobExecutionTrend(**item) for item in trend_data]


@router.get("/scheduler/status")
async def get_scheduler_status(
    current_user: User = Depends(get_current_user)
):
    """获取调度器状态"""
    return job_scheduler.get_scheduler_status()


@router.post("/scheduler/reload")
async def reload_scheduler(
    current_user: User = Depends(get_current_user)
):
    """重新加载调度器"""
    job_scheduler.load_all_jobs_from_db()
    return {"message": "调度器重新加载成功"}


# ==================== 任务处理器管理 ====================

@router.get("/handlers/")
async def get_job_handlers(
    current_user: User = Depends(get_current_user)
):
    """获取可用的任务处理器列表"""
    return {
        "handlers": list(job_scheduler.job_handlers.keys()),
        "total": len(job_scheduler.job_handlers)
    }